import express from 'express';
import { User } from '../models/User.js';
import { Session } from '../models/Session.js';
import { AccessLog } from '../models/AccessLog.js';
import { TOTPService } from '../services/totpService.js';
import { generateToken, authenticate } from '../middleware/auth.js';
import { log } from '../utils/logger.js';
import { getClientIP } from '../utils/ipHelper.js';

const router = express.Router();

/**
 * 用户登录
 */
router.post('/login', async (req, res) => {
  try {
    const { username, password, totpToken } = req.body;
    const ip = getClientIP(req);
    const userAgent = req.get('user-agent');

    // 验证输入
    if (!username || !password) {
      return res.status(400).json({
        success: false,
        message: '用户名和密码不能为空'
      });
    }

    // 查找用户
    const user = await User.findByUsername(username);
    if (!user) {
      log.auth('登录失败：用户不存在', { username, ip });
      await AccessLog.create(null, ip, '登录失败', `用户不存在: ${username}`, userAgent);
      return res.status(401).json({
        success: false,
        message: '用户名或密码错误'
      });
    }

    // 验证密码
    const isValidPassword = await User.verifyPassword(password, user.password);
    if (!isValidPassword) {
      log.auth('登录失败：密码错误', { username, ip });
      await AccessLog.create(user.id, ip, '登录失败', '密码错误', userAgent);
      return res.status(401).json({
        success: false,
        message: '用户名或密码错误'
      });
    }

    // 如果启用了TOTP，需要验证动态验证码
    if (user.totp_enabled) {
      if (!totpToken) {
        return res.status(400).json({
          success: false,
          message: '请输入谷歌验证码',
          requireTotp: true
        });
      }

      const isValidTotp = TOTPService.verifyToken(user.totp_secret, totpToken);
      if (!isValidTotp) {
        log.auth('登录失败：TOTP验证码错误', { username, ip });
        await AccessLog.create(user.id, ip, '登录失败', 'TOTP验证码错误', userAgent);
        return res.status(401).json({
          success: false,
          message: '验证码错误'
        });
      }
    }

    // 生成token
    const token = generateToken(user.id);

    // 创建会话（自动使旧会话失效，实现单用户在线）
    const sessionTimeout = parseInt(process.env.SESSION_TIMEOUT || '30');
    const expiresAt = new Date(Date.now() + sessionTimeout * 60 * 1000);
    await Session.create(user.id, token, ip, userAgent, expiresAt);

    // 记录日志
    await AccessLog.create(user.id, ip, '用户登录', `用户登录成功: ${username}`, userAgent);
    log.auth(`用户登录成功: ${username}`, { userId: user.id, ip });

    res.json({
      success: true,
      message: '登录成功',
      data: {
        token,
        user: {
          id: user.id,
          username: user.username,
          email: user.email,
          totpEnabled: !!user.totp_enabled
        }
      }
    });
  } catch (error) {
    log.error('登录失败', { error: error.message });
    res.status(500).json({
      success: false,
      message: '登录失败，请稍后再试'
    });
  }
});

/**
 * 用户登出
 */
router.post('/logout', authenticate, async (req, res) => {
  try {
    const { token, user, clientIP } = req;

    // 使会话失效
    await Session.deactivate(token);

    // 记录日志
    await AccessLog.create(user.id, clientIP, '用户登出', `用户登出: ${user.username}`, req.get('user-agent'));
    log.auth(`用户登出: ${user.username}`, { userId: user.id, ip: clientIP });

    res.json({
      success: true,
      message: '登出成功'
    });
  } catch (error) {
    log.error('登出失败', { error: error.message });
    res.status(500).json({
      success: false,
      message: '登出失败'
    });
  }
});

/**
 * 获取当前用户信息
 */
router.get('/me', authenticate, (req, res) => {
  res.json({
    success: true,
    data: req.user
  });
});

/**
 * 强制登出所有会话
 */
router.post('/logout-all', authenticate, async (req, res) => {
  try {
    const { user, clientIP } = req;

    // 使用户的所有会话失效
    const count = await Session.deactivateAllByUser(user.id);

    // 记录日志
    await AccessLog.create(user.id, clientIP, '强制登出', `强制登出所有会话: ${count}个`, req.get('user-agent'));
    log.auth(`用户强制登出所有会话: ${user.username}`, { userId: user.id, count, ip: clientIP });

    res.json({
      success: true,
      message: `已登出${count}个会话`,
      data: { count }
    });
  } catch (error) {
    log.error('强制登出失败', { error: error.message });
    res.status(500).json({
      success: false,
      message: '强制登出失败'
    });
  }
});

/**
 * 生成TOTP密钥和二维码
 */
router.get('/totp/generate', authenticate, async (req, res) => {
  try {
    const { user } = req;
    
    // 生成TOTP密钥和二维码
    const { secret, qrcode, otpauth_url } = await TOTPService.generateSecret(user.username);
    
    log.auth('生成TOTP密钥', { userId: user.id });
    
    res.json({
      success: true,
      message: '二维码生成成功',
      data: {
        secret,
        qrcode,
        otpauth_url
      }
    });
  } catch (error) {
    log.error('生成TOTP密钥失败', { error: error.message });
    res.status(500).json({
      success: false,
      message: '生成二维码失败'
    });
  }
});

/**
 * 启用TOTP认证
 */
router.post('/totp/enable', authenticate, async (req, res) => {
  try {
    const { user } = req;
    const { secret, token } = req.body;
    
    if (!secret || !token) {
      return res.status(400).json({
        success: false,
        message: '密钥和验证码不能为空'
      });
    }
    
    // 验证令牌
    const isValid = TOTPService.verifyToken(secret, token);
    if (!isValid) {
      return res.status(400).json({
        success: false,
        message: '验证码错误，请重试'
      });
    }
    
    // 启用TOTP
    await User.enableTOTP(user.id, secret);
    
    await AccessLog.create(user.id, req.clientIP, '启用TOTP', '启用谷歌验证器', req.get('user-agent'));
    log.auth('TOTP认证已启用', { userId: user.id });
    
    res.json({
      success: true,
      message: '谷歌验证器启用成功'
    });
  } catch (error) {
    log.error('启用TOTP失败', { error: error.message });
    res.status(500).json({
      success: false,
      message: '启用失败'
    });
  }
});

/**
 * 禁用TOTP认证
 */
router.post('/totp/disable', authenticate, async (req, res) => {
  try {
    const { user } = req;
    const { token } = req.body;
    
    if (!token) {
      return res.status(400).json({
        success: false,
        message: '请输入验证码'
      });
    }
    
    // 验证令牌
    const isValid = TOTPService.verifyToken(user.totp_secret, token);
    if (!isValid) {
      return res.status(400).json({
        success: false,
        message: '验证码错误'
      });
    }
    
    // 禁用TOTP
    await User.disableTOTP(user.id);
    
    await AccessLog.create(user.id, req.clientIP, '禁用TOTP', '禁用谷歌验证器', req.get('user-agent'));
    log.auth('TOTP认证已禁用', { userId: user.id });
    
    res.json({
      success: true,
      message: '谷歌验证器已禁用'
    });
  } catch (error) {
    log.error('禁用TOTP失败', { error: error.message });
    res.status(500).json({
      success: false,
      message: '禁用失败'
    });
  }
});

/**
 * 获取TOTP状态
 */
router.get('/totp/status', authenticate, async (req, res) => {
  try {
    const { user } = req;
    const userData = await User.findById(user.id);
    
    res.json({
      success: true,
      data: {
        enabled: !!userData.totp_enabled
      }
    });
  } catch (error) {
    log.error('获取TOTP状态失败', { error: error.message });
    res.status(500).json({
      success: false,
      message: '获取状态失败'
    });
  }
});

export default router;

